package net.yeah.mickey_zhouyou.util.fcs;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.script.ScriptContext;

import net.yeah.mickey_zhouyou.util.fcs.elem.Fcs;
import net.yeah.mickey_zhouyou.util.fcs.serialize.IConvertor;
import net.yeah.mickey_zhouyou.util.fcs.serialize.XStreamConvertor;

public class FCS {

	private static Map<String, FCS> cache = new ConcurrentHashMap<String, FCS>();

	public static FCS getInstance(String script) throws IOException {
		FCS fcs = cache.get(script);
		if (fcs == null)
			synchronized (cache) {
				fcs = cache.get(script);
				if (fcs == null) {
					InputStream is = null;
					Reader reader = null;
					try {
						is = new ByteArrayInputStream(script.getBytes());
						reader = new InputStreamReader(is);
						fcs = createInstance(reader);
						cache.put(script, fcs);
					} finally {
						if (is != null)
							try {
								is.close();
							} catch (Exception e) {
								e.printStackTrace();
							}
						if (reader != null)
							try {
								reader.close();
							} catch (Exception e) {
								e.printStackTrace();
							}
					}
				}
			}
		return fcs;
	}

	public static FCS createInstance(Reader reader) throws IOException {
		return new FCS(reader);
	}

	private FCS(Reader reader) throws IOException {
		this(reader, new XStreamConvertor());
	}

	private FCS(Reader reader, IConvertor objConvertor) throws IOException {
		this.objConvertor = objConvertor;
		this.fcs = Fcs.create(new ReaderWrapper(reader));
	}

	private Fcs fcs = null;
	private IConvertor objConvertor = null;

	public void eval(ScriptContext context) {
		fcs.eval(objConvertor, context);
	}

	public static void main(String[] args) throws Exception {
		String script = "a = b;\nbill.addr[1,3-5]((!(a < b)) || ((c >= 'd'))).xx = 'abc';";
		FCS fcs = FCS.getInstance(script);
		System.out.println(fcs);
	}
}
